﻿using K4os.Compression.LZ4;
using MySql.Data.MySqlClient;
using Mysqlx.Crud;
using Mysqlx.Expr;
using NewChillers.Helpers;
using NewChillers.Models;
using NewChillers.Models.Events;
using NewChillers.Utils;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace NewChillers.ViewModels
{
    public class LogViewModel : ObservableObject
    {
        private List<LogModel> _logList; // 日志列表
        private bool _isLogListLoading;
        private UserModel _currentUser;
        private readonly ShellViewModel _shellViewModel;

		private DateTime? _startTime; // 开始时间
        private DateTime? _endTime; // 截止时间
        private List<string> _logLevelSource; // 日志级别 下拉框
        private List<string> _userNameSource; // 操作者 下拉框
        private string _selectedLogLevel;
        private string _selectedUserName;

        public List<LogModel> LogList
        {
            get => _logList;
            set => SetProperty(ref _logList, value);
        }
        public bool IsLogListLoading
        {
            get => _isLogListLoading;
            set => SetProperty(ref _isLogListLoading, value);
        }
        public UserModel CurrentUser // 用户 只读就行
        {
            get => _currentUser;
        }
        public DateTime? StartTime
        {
            get => _startTime;
            set => SetProperty(ref _startTime, value);
        }
        public DateTime? EndTime
        {
            get => _endTime;
            set => SetProperty(ref _endTime, value);
        }
        public List<string> LogLevelSource
        {
            get => _logLevelSource;
            set => SetProperty(ref _logLevelSource, value);
        }
        public List<string> UserNameSource
        {
            get => _userNameSource;
            set => SetProperty(ref _userNameSource, value);
        }
        public string SelectedLogLevel
        {
            get => _selectedLogLevel;
            set => SetProperty(ref _selectedLogLevel, value);
        }
        public string SelectedUserName
        {
            get => _selectedUserName;
            set => SetProperty(ref _selectedUserName, value);
        }

        public ICommand CopyCommand { get; }
        public ICommand RefreshCommand { get; }
        public ICommand SearchCommand { get; }

        public LogViewModel(UserModel userModel, ShellViewModel shellViewModel)
        {
            _currentUser = userModel;
            _shellViewModel = shellViewModel;
            
            // 初始化列表
            _logLevelSource = new List<string>();
            _userNameSource = new List<string>();

            InitDatePickerAndComboBox(); // 初始化筛选条件
            // 页面打开时自动加载 启动异步方法 但不等待它完成 忽略返回的 Task 对象
            _ = InitLogListAsync();

            CopyCommand = new RelayCommand<LogModel>(ExecuteCopy);
            RefreshCommand = new RelayCommand(ExecuteRefresh);
            SearchCommand = new RelayCommand(ExecuteSearch);

            // 订阅
            _shellViewModel.UserInfoUpdate += OnUserInfoUpdate;
        }

        #region 查询
        private async void ExecuteSearch(object obj)
        {
            await InitLogListAsync();  // 需要等待加载完成
        }
        #endregion

        #region 初始化
        /// <summary>
        /// 初始化筛选条件
        /// </summary>
        private void InitDatePickerAndComboBox()
        {
            StartTime = null;
            EndTime = null;

            LogLevelSource?.Clear();
            LogLevelSource.Add("错误");
            LogLevelSource.Add("警告");
            LogLevelSource.Add("信息");
            LogLevelSource.Add("调试");
            // 确保没有默认选中值
            SelectedLogLevel = null;

            UserNameSource?.Clear();
            string sql = "select user_name from user_info";
            DataTable dt = MysqlHelper.ExecuteQuery(sql);
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                UserNameSource.Add(dt.Rows[i]["user_name"].ToString());
            }
            // 确保没有默认选中值
            SelectedUserName = null;
        }
        #endregion

        #region 刷新日志列表功能
        private async void ExecuteRefresh(object obj)
        {
            InitDatePickerAndComboBox();
            await InitLogListAsync();  // 需要等待加载完成
            //MsgBoxHelper.Info("刷新完成"); // 这行会等待异步方法完成后执行
        }
        #endregion

        #region 复制功能
        /// <summary>
        /// 复制日志
        /// </summary>
        private void ExecuteCopy(LogModel log)
        {
            if (log == null)
                return;

            try
            {
                // 构建要复制的文本内容
                string logContent = FormatLogContent(log);

                // 复制到剪贴板
                Clipboard.SetText(logContent);

                // 显示成功消息
                MsgBoxHelper.Info("日志内容已复制到剪贴板");

                // 记录操作日志
                LogHelper.Info(this.GetType(), $"[复制日志]|" + $"复制日志记录 日志序号:{log.LogId}", _currentUser.UserAccount);
            }
            catch (Exception ex)
            {
                MsgBoxHelper.Error($"复制失败: {ex.Message}");
                LogHelper.Error(this.GetType(), "[复制日志]|" + "复制日志内容失败", ex, _currentUser.UserAccount);
            }
        }

        /// <summary>
        /// 格式化日志内容
        /// </summary>
        private string FormatLogContent(LogModel log)
        {
            var alog = new StringBuilder();
            alog.AppendLine($"序号: {log.LogId}");
            alog.AppendLine($"记录时间: {log.LogTime:yyyy-MM-dd HH:mm:ss}");
            alog.AppendLine($"日志级别: {log.LogLevel}");
            alog.AppendLine($"记录类: {log.Logger}");
            alog.AppendLine($"操作者: {log.Operator}");
            alog.AppendLine($"内容: {log.LogMessage}");
            return alog.ToString();
        }
        #endregion

        #region 更新当前登录用户的信息 事件处理
        /// <summary>
        /// 接收到通知
        /// </summary>
        private void OnUserInfoUpdate(object sender, UserInfoUpdateEventArgs e)
        {
            // 空值检查，避免NullReferenceException
            if (e?.UpdatedUser != null)
            {
                _currentUser = e.UpdatedUser;
                Debug.WriteLine("Log页面|用户信息已更新");
            }
            else
            {
                Debug.WriteLine("收到空的事件参数");
            }
        }

        /// <summary>
        /// 析构函数中的事件取消订阅
        /// </summary>
        ~LogViewModel()
        {
            _shellViewModel.UserInfoUpdate -= OnUserInfoUpdate;
        }
        #endregion

        #region 显示
        /// <summary>
        /// 显示日志列表
        /// </summary>
        private async Task InitLogListAsync()
        {
            // 防止重复加载
            if (IsLogListLoading)
                return;

            IsLogListLoading = true;

            //try
            //{
            //    var logs = await Task.Run(() =>
            //    {
            //        string sql = @"SELECT * FROM log_info 
            //                        ORDER BY log_id DESC";

            //        Func<IDataRecord, LogModel> mapper = reader => new LogModel
            //        {
            //            LogId = Convert.ToInt32(reader["log_id"]),
            //            LogTime = Convert.ToDateTime(reader["log_time"]),
            //            LogLevel = reader["log_level"].ToString(),
            //            Logger = reader["logger"].ToString(),
            //            Operator = reader["operator"].ToString(),
            //            LogMessage = reader["log_message"].ToString()
            //        };

            //        return MysqlHelper.QueryList<LogModel>(sql, mapper);
            //    });

            //    LogList = logs;
            //}
            try
            {
                var logs = await Task.Run(() =>
                {
                    // SELECT* FROM log_info WHERE 1 = 1 AND log_time > '2025-10-09' AND log_time < '2025-10-10' AND log_level = 'INFO' AND operator = '2' ORDER BY log_id DESC

                    List<MySqlParameter> parameters = new List<MySqlParameter>();

                    //string sql = @"SELECT * FROM log_info WHERE 1 = 1";
                    string sql = @"SELECT l.*, u.user_name 
                                    FROM log_info l 
                                    LEFT JOIN user_info u ON l.operator = u.user_account 
                                    WHERE 1 = 1";

                    // 界面显示值 → 数据库存储值
                    var logLevelMap = new Dictionary<string, string>
                    {
                        { "错误", "ERROR" },  // 界面显示"错误"，数据库存"ERROR"
                        { "警告", "WARN" },   // 界面显示"警告"，数据库存"WARN"
                        { "信息", "INFO" },   // 界面显示"信息"，数据库存"INFO"
                        { "调试", "DEBUG" }   // 界面显示"调试"，数据库存"DEBUG"
                    };

                    if (StartTime != null)
                    {
                        sql += " AND log_time > @StartTime";
                        //parameters.Add(new MySqlParameter("@StartTime", StartTime));
                        parameters.Add(new MySqlParameter("@StartTime", StartTime.Value.Date));  // 只取日期部分
                    }
                    if (EndTime != null)
                    {
                        sql += " AND log_time < @EndTime";
                        //parameters.Add(new MySqlParameter("@EndTime", EndTime));
                        parameters.Add(new MySqlParameter("@EndTime", EndTime.Value.Date.AddDays(1)));  // 结束日期的下一天
                    }
                    if (!string.IsNullOrEmpty(SelectedLogLevel))
                    {
                        string dbLogLevel = logLevelMap[SelectedLogLevel]; // 界面显示值 → 数据库存储值
                        sql += " AND log_level = @LogLevel";
                        parameters.Add(new MySqlParameter("@LogLevel", dbLogLevel));
                    }
                    if (!string.IsNullOrEmpty(SelectedUserName))
                    {
                        // 先查询用户ID
                        string userId = GetUserIdByName(SelectedUserName);
                        if (!string.IsNullOrEmpty(userId))
                        {
                            sql += " AND operator = @Operator";
                            parameters.Add(new MySqlParameter("@Operator", userId));
                        }
                    }

                    sql += " ORDER BY log_id DESC";

                    Func<IDataRecord, LogModel> mapper = reader => new LogModel
                    {
                        LogId = Convert.ToInt32(reader["log_id"]),
                        LogTime = Convert.ToDateTime(reader["log_time"]),
                        LogLevel = reader["log_level"].ToString(),
                        Logger = reader["logger"].ToString(),
                        //Operator = reader["operator"].ToString(),
                        Operator = reader["user_name"].ToString(), // 这里改为显示昵称
                        LogMessage = reader["log_message"].ToString()
                    };

                    return MysqlHelper.ExecuteQuery<LogModel>(sql, mapper, parameters.ToArray());
                });

                LogList = logs;
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), "[加载日志]|" + "日志列表加载失败", ex, _currentUser.UserAccount);
                LogList = new List<LogModel>();
            }
            finally
            {
                IsLogListLoading = false;
            }
        }

        /// <summary>
        /// 根据用户名获取用户ID
        /// </summary>
        private string GetUserIdByName(string selectedUserName)
        {
            try
            {
                string sql = "SELECT user_account FROM user_info WHERE user_name = @UserName";
                var parameter = new MySqlParameter("@UserName", selectedUserName);

                DataTable dt = MysqlHelper.ExecuteQuery(sql, parameter);
                if (dt.Rows.Count > 0)
                {
                    return dt.Rows[0]["user_account"].ToString();
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), "[获取用户ID]|" + $"根据用户名'{selectedUserName}'获取用户ID失败", ex, _currentUser.UserAccount);
            }

            return null;
        }
        #endregion

    }
}
